package com.xy.service.impl;

import com.xy.entity.FileEntity;
import com.xy.exception.enums.FileExceptionEnum;
import com.xy.repository.IFileDao;
import com.xy.service.IFileHandlerService;
import com.xy.utils.AssertUtil;
import com.xy.utils.ConfigUtil;
import com.xy.vo.FileVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Service
public class FileHandlerServiceImpl implements IFileHandlerService {

    private final IFileDao fileDao;
    private final String FileTypeSuffix = "\\.(jpg|png|gif|jpeg|doc|docx)$";
    @Autowired
    public FileHandlerServiceImpl(IFileDao fileDao) {
        this.fileDao = fileDao;
    }

    @Override
    @Transactional(rollbackFor = Exception.class, timeout = 3600)
    public FileVO importFile(MultipartFile file) {
            FileEntity fileEntity = importSingleFile(file);
            AssertUtil.assertNotNull(fileEntity, FileExceptionEnum.UPLOAD_FAIL_NO_FILE);
            //保存到数据库
            FileEntity savedFile = fileDao.saveAndFlush(fileEntity);
            return new FileVO(savedFile.getId(),savedFile.getOriginalName(),savedFile.getStoredName()) ;
    }

    @Override
    @Transactional(rollbackFor = Exception.class, timeout = 3600)
    public List<FileVO> importFiles(List<MultipartFile> files){
        AssertUtil.assertTrue(files != null || files.size() != 0, FileExceptionEnum.UPLOAD_FAIL_NO_FILE);
        AssertUtil.assertTrue(files.size() < 10, FileExceptionEnum.UPLOAD_FAIL_FILE_SIZE_OVER_LIMIT);
        List<FileEntity> fileEntities = new ArrayList<>();
        files.forEach(file -> {
            fileEntities.add(importSingleFile(file));
        });
        List<FileEntity> savedFileVOList = fileDao.saveAllAndFlush(fileEntities);
        return savedFileVOList.stream().map(fileEntity -> new FileVO(fileEntity.getId(), fileEntity.getOriginalName(),fileEntity.getStoredName())).collect(Collectors.toList());
    }

    public FileEntity importSingleFile(MultipartFile file) {
        AssertUtil.assertNotNull(file, FileExceptionEnum.UPLOAD_FAIL_NO_FILE);
        try {
            // 1. 生成唯一文件名（UUID + 时间戳）
            String originalName = file.getOriginalFilename();
            String fileExt = originalName.substring(originalName.lastIndexOf("."));
            String uuid = UUID.randomUUID().toString().replace("-", "");
            String storedName = uuid + "_" + System.currentTimeMillis() + fileExt;
            AssertUtil.assertTrue(fileExt.matches(FileTypeSuffix), FileExceptionEnum.UPLOAD_FAIL_FILE_TYPE_NOT_SUPPORT);
            AssertUtil.assertTrue(file.getSize() < 10 * 1024 * 1024, FileExceptionEnum.UPLOAD_FAIL_FILE_SIZE_NOT_SUPPORT);
            // 2. 创建存储目录
            Path uploadPath = Paths.get(ConfigUtil.readProperty("file_path"));
            if (!Files.exists(uploadPath)) {
                Files.createDirectories(uploadPath);
            }
            // 3. 保存文件到本地
            Path filePath = uploadPath.resolve(storedName);
            Files.copy(file.getInputStream(), filePath, StandardCopyOption.REPLACE_EXISTING);
            return new FileEntity(null, originalName, storedName, filePath.toAbsolutePath().normalize().toString(), null, file.getSize());
        } catch (IOException e) {
            AssertUtil.assertTrue(false, FileExceptionEnum.UPLOAD_FAIL_FILE_IMPORT_FAIL);
        }
        return null;
    }


}
